﻿package bdz.controls
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.ui.Mouse;
	
	import bdz.math.trigo;
	
	/**
	 * ...
	 * @author ...
	 */
	public class MCModifier extends MovieClip
	{
		private var modTarget:DisplayObject;
		
		private var resizeKnob:MovieClip;
		private var rotateKnob:MovieClip;
		private var handles:MovieClip;
		private var cover:MovieClip;
		private var action:String;
		private var axis:Point = new Point();
		private var omat:Matrix;
		private var tmat:Matrix;
		private var prot:Number;
		
		private var iangle:Number;
		private var rangle:Number;
		
		function MCModifier(targ:DisplayObject) {
			modTarget = targ;
			addEventListener(Event.ADDED_TO_STAGE, initialize);
			
		}
		private function initialize(evt:Event):void {
			cover = new MovieClip();
			cover.graphics.lineStyle(.1, 0x333333, .3);
			cover.graphics.beginFill(0x333333, .1);
			cover.graphics.drawRect(0, 0, modTarget.width, modTarget.height);
			cover.graphics.endFill();
			x = modTarget.x;
			y = modTarget.y;
			addChild(cover);
			handles = new MovieClip();
			addChild(handles);
			createHandles();
			cover.addEventListener(MouseEvent.MOUSE_DOWN, onModifierDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, clearAll);
			updateAxis();
		}
		private function updateAxis():void {
			axis.x = cover.width / 2;
			axis.y = cover.height / 2;
		}
		private function clearAll(evt:MouseEvent):void {
			if (action == "move") {
				updateTarget();
			}
			action = "";
			stopDrag();
			removeEventListener(Event.ENTER_FRAME, updateTarget);
		}
		private function onResizeDown(evt:MouseEvent):void {
			action = "resize";
			addEventListener(Event.ENTER_FRAME, updateTarget);
		}
		private function onRotateDown(evt:MouseEvent):void {
			action = "rotate";
			iangle = trigo.getAngle( { x:mouseX, y:mouseY }, axis, true);
			rangle = trigo.getAngle( { x:resizeKnob.x, y:resizeKnob.y}, axis, true);
			omat = cover.transform.matrix.clone();
			tmat = modTarget.transform.matrix.clone();
			addEventListener(Event.ENTER_FRAME, updateTarget);	
		}
		private function repositionHandles():void {
			
			var pangle:Number = trigo.getAngle( rotateKnob, axis, true);
			var rad:Number = Math.round(trigo.getProximity(axis, rotateKnob));
			resizeKnob.x = trigo.positionFromRadius(pangle+rangle*2, rad, "x", axis);
			resizeKnob.y = trigo.positionFromRadius(pangle+rangle*2, rad, "y", axis);
		}
		private function checkRotation():void {
			var nmat:Matrix = omat.clone();
			
			var pangle:Number = trigo.getAngle( { x:mouseX, y:mouseY }, axis, true);
			var rad:Number = Math.round(trigo.getProximity(axis, rotateKnob));
			
			
			rotateKnob.x = trigo.positionFromRadius(pangle, rad, "x", axis);
			rotateKnob.y = trigo.positionFromRadius(pangle, rad, "y", axis);
			
			
			resizeKnob.x = trigo.positionFromRadius(pangle+rangle*2, rad, "x", axis);
			resizeKnob.y = trigo.positionFromRadius(pangle+rangle*2, rad, "y", axis);
			
			var rot:Number = trigo.getAngle( { x:mouseX, y:mouseY }, axis, true )-iangle;
			

			if(prot != rot){
				nmat.tx -= axis.x;
				nmat.ty -= axis.y;
				nmat.rotate(rot);
				nmat.tx += axis.x;
				nmat.ty += axis.y;
				
				var cmat:Matrix = nmat.clone()
				cmat.tx -= modTarget.width / 2;
				cmat.ty -= modTarget.height / 2;
				cmat.rotate(rot);
				cmat.tx += modTarget.width / 2;
				cmat.ty += modTarget.height / 2;
				
				//modTarget.transform.matrix = cmat;
				cover.transform.matrix = nmat;
				
				
				
				modTarget.transform.matrix.tx = transform.matrix.tx;
				
				prot = rot;
				
			}
			
			
			
			
		}
		private function onModifierDown(evt:MouseEvent):void {
			action = "move";
			startDrag(false);
			addEventListener(Event.ENTER_FRAME, updateTarget);
		}
		private function updateTarget(evt:Event = null) {
			switch(action) {
				case "move":
					modTarget.x = x;
					modTarget.y = y;
				break;
				case "resize":
					resizeKnob.x = handles.mouseX;
					checkResizeAspect();
				break;
				case "rotate":
					checkRotation();
				break;
			}
		}
		private function checkResizeAspect():void {
			var newh:Number = (resizeKnob.x / cover.width) * cover.height;
			
			cover.width = resizeKnob.x;
			rotateKnob.x = cover.width;
			cover.height = newh;
			resizeKnob.y = newh;
			
			var cmat:Matrix = cover.transform.matrix.clone()
			cmat.tx = modTarget.transform.matrix.tx;
			cmat.ty = modTarget.transform.matrix.ty;
			
			modTarget.transform.matrix = cmat;
			
			
			updateAxis();
		}
		
		private function createHandles():void {
			resizeKnob = new MovieClip();
			resizeKnob.graphics.lineStyle(.1, 0x000000);
			resizeKnob.graphics.beginFill(0xebebeb, 1);
			resizeKnob.graphics.drawRect(-5, -5, 10, 10);
			resizeKnob.graphics.endFill();
			
			rotateKnob = new MovieClip();
			rotateKnob.graphics.lineStyle(.1, 0x000000);
			rotateKnob.graphics.beginFill(0xebebeb, 1);
			rotateKnob.graphics.drawCircle(0, 0, 5);
			rotateKnob.graphics.endFill();
			
			resizeKnob.x = modTarget.width;
			resizeKnob.y = modTarget.height;
			
			rotateKnob.x = modTarget.width;
			
			resizeKnob.addEventListener(MouseEvent.MOUSE_DOWN, onResizeDown);
			rotateKnob.addEventListener(MouseEvent.MOUSE_DOWN, onRotateDown);
			
			
			
			handles.addChild(resizeKnob);
			handles.addChild(rotateKnob);
		}
		public function activate():void {
			
		}
		public function deactivate():void {
			
		}
		
	}
	
}